home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Whiteline: delta
/
whiteline CD Series - delta.iso
/
whitelin
/
share
/
boxkite
/
beispiel.c
next >
Wrap
C/C++ Source or Header
|
1995-11-25
|
10KB
|
397 lines
/*
* Beispiel-Programm zur Benutzung des Selectric-Protokolls mit BoxKite
* unter MiNT/MultiTOS/MagiC/MagiC Mac
* (c) Harald Becker, 12.5.1994. Übersetzt mit Pure C und DEFAULT.PRJ.
*
* Diesen Code dürfen Sie nach Belieben verwenden und ganz oder in in Auszügen
* in Ihre Programme aufnehmen.
*
* HB 061095:
* Erweitert um eine Anwendung für den Message-Callback in BoxKite 1.7x
* Dazu wird hinter dem Fileselector ein kleines Fenster geöffnet,
* das über den Message-Callback gezeichnet wird. Es kann auch
* verschoben werden, falls das Betriebssystem das Verschieben hinten-
* liegender Fenster erlaubt.
*
* HB 131095:
* Inzwischen demonstriert das Programm alle drei möglichen Rückgabeformen.
* Die Auswahl erfolgt zur Compile-Zeit über die Konstante 'RETURN'.
*/
#include <stdio.h>
#include <aes.h>
#include <tos.h>
#include <string.h>
/*
* Diese Konstante steuert, welche Rückgabemethode das Beispielprogramm
* bei BoxKite anfordert. Mögliche Werte:
*
* 1: Rückgabe über ein Feld von Stringzeigern
* 2: Rückgabe über einen String (mit trennenden Leerzeichen)
* 3: Rückgabe über Funktionen
*/
#define RETURN 1
/*
* Diese Struktur wird von BoxKite gefüllt. Sie ist identisch mit der
* TOS-DTA, sieht jedoch Platz für lange Datenamen vor.
*/
typedef struct
{ char d_reserved[21];
unsigned char d_attrib;
unsigned int d_time;
unsigned int d_date;
unsigned long d_length;
char d_fname[34];
} XDTA;
/*
* Die Selectric-Struktur.
*/
typedef struct
{ unsigned long id; /* Selectric ID (SLCT) */
unsigned int version; /* version (BCD-Format) */
struct
{ unsigned : 7; /* reserved */
unsigned pthsav : 1;
unsigned stdest : 1;
unsigned : 1;
unsigned numsrt : 1; /* numerisches Sortieren */
unsigned lower : 1;
unsigned dclick : 1; /* Ordner mit Doppelklick */
unsigned hidden : 1; /* versteckte Dateien */
unsigned onoff : 1; /* Fileselector AN/AUS */
} config;
int sort; /* sort-mode (neg. = rev.) */
int num_ext; /* number of extensions */
char *(*ext)[]; /* preset extensions */
int num_paths; /* number of paths */
char *(*paths)[]; /* preset paths */
int comm; /* communication word */
int in_count; /* input counter */
void *in_ptr; /* input pointer */
int out_count; /* output counter */
void *out_ptr; /* output pointer */
int cdecl (*get_first)(XDTA *dta, int attrib);
int cdecl (*get_next)(XDTA *dta);
int cdecl (*release_dir)(void);
} SLCT_STR;
typedef struct
{ long id;
long value;
} COOKIE;
long Supexec(long (*codeptr)());
SLCT_STR *slct_cookie;
/*
* Prototyp des Message-Handlers.
*/
typedef void cdecl (* FSEL_CALLBACK)(int *msg);
/*
* Prototyp des erweiterten Bindings.
*/
int cdecl fsel_boxinput(char *path, char *name, int *button, char *label, FSEL_CALLBACK callback);
/*
* Variablen für die Rückgabe der Dateinamen.
*/
#if RETURN == 1
char name1[34], name2[34], name3[34];
char *nameptrs[] = { name1, name2, name3 };
#elif RETURN == 2
char stringbuf[256];
#else
int cdecl (*p_get_first)(XDTA *dta, int attrib);
int cdecl (*p_get_next)(XDTA *dta);
int cdecl (*p_release_dir)(void);
#endif
int name_count; /* Anzahl der gelieferten Namen */
int window; /* Fensterkennung */
OBJECT contents = /* Fensterinhalt */
{ -1, -1, -1, G_BOXCHAR, 0, 0, 0x2aff11f0, 1, 1, 1, 1 };
int xdesk, ydesk, wdesk, hdesk;
/*
* Gibt die Adresse des Cookie-Jar zurück. Mit Supexec() aufrufen.
*/
long get_cookiejar(void)
{ return *((long *)0x05a0l);
}
/*
* Durchsucht den Cookie Jar nach einem cookie mit gegebener id und
* liefert dessen Wert zurück.
*/
long get_cookie(long id)
{ long sav;
COOKIE *cookiejar;
int i = 0;
cookiejar = (COOKIE *)Supexec(get_cookiejar);
if ( cookiejar )
{ while ( cookiejar[i].id )
{ if ( cookiejar[i].id == id )
return cookiejar[i].value;
i++;
}
}
return 0L;
}
/*
* Prüft, ob am 'FSEL'-cookie ein Selectric-1.02-kompatibler Fileselector
* hängt. Im Erfolgsfall wird die Datenstruktur hinter dem Cookie für die
* gewünschte Rückgabeform initialisiert.
* Sollte mit Supexec aufgerufen werden, da der Speicher immerhin einem
* fremden Prozeß gehört.
*/
long setup_selector(void)
{ if ( slct_cookie && slct_cookie->id == 'SLCT' && slct_cookie->version >= 0x102 )
{
#if RETURN == 1
slct_cookie->comm = 1;
slct_cookie->out_count = 3;
slct_cookie->out_ptr = nameptrs;
#elif RETURN == 2
slct_cookie->comm = 3;
slct_cookie->out_count = 5;
slct_cookie->out_ptr = stringbuf;
#else
slct_cookie->comm = 9;
p_get_first = slct_cookie->get_first;
p_get_next = slct_cookie->get_next;
p_release_dir = slct_cookie->release_dir;
#endif
return 1;
}
return 0;
}
/*
* Liest die Anzahl der gelieferten Namen aus der FSEL-Struktur.
*/
long get_out_count(void)
{ name_count = slct_cookie->out_count;
return 0;
}
/*
* Fragt das aktuelle Laufwerk und den aktuellen Pfad ab.
*/
void getpath(char *p)
{ int drv;
drv = Dgetdrv();
*p++ = drv + 'A';
*p++ = ':';
Dgetpath(p, drv);
p += strlen(p) - 1;
if ( *p != '\\' )
{ p++;
*p++ = '\\';
*p = 0;
}
}
/*
* Die folgenden vier Funktionen befassen sich nur mit dem Zeichnen
* des Fensterinhaltes. Ich denke, die Methode hat sich inzwischen
* herumgesprochen.
*/
int min(int a, int b)
{ return ( a < b ? a : b );
}
int max(int a, int b)
{ return ( a > b ? a : b );
}
int rc_intersect(GRECT *p1, GRECT *p2)
{ int tx, ty, tw, th;
tw = min(p2->g_x + p2->g_w, p1->g_x + p1->g_w);
th = min(p2->g_y + p2->g_h, p1->g_y + p1->g_h);
tx = max(p2->g_x, p1->g_x);
ty = max(p2->g_y, p1->g_y);
p2->g_x = tx;
p2->g_y = ty;
p2->g_w = tw - tx;
p2->g_h = th - ty;
return( (tw > tx) && (th > ty) );
}
void window_redraw(int handle, int x, int y, int w, int h)
{ GRECT r1, r2, world;
wind_update(BEG_UPDATE);
r2.g_x = x;
r2.g_y = y;
r2.g_w = w;
r2.g_h = h;
world.g_x = xdesk;
world.g_y = ydesk;
world.g_w = wdesk;
world.g_h = hdesk;
wind_get(handle, WF_FIRSTXYWH, &r1.g_x, &r1.g_y, &r1.g_w, &r1.g_h);
while ( r1.g_w && r1.g_h )
{ if ( rc_intersect(&world, &r1) && rc_intersect(&r2, &r1) )
objc_draw(&contents, ROOT, MAX_DEPTH, r1.g_x, r1.g_y, r1.g_w, r1.g_h);
wind_get(handle, WF_NEXTXYWH, &r1.g_x, &r1.g_y, &r1.g_w, &r1.g_h);
}
wind_update(END_UPDATE);
}
/*
* Die Einsprungadresse dieser Funktion wird als Callback an BoxKite
* übergeben.
*/
void cdecl message_handler(int *msg)
{ switch ( msg[0] )
{ case WM_REDRAW:
wind_get(msg[3], WF_WORKXYWH, &contents.ob_x, &contents.ob_y, &contents.ob_width, &contents.ob_height);
window_redraw(msg[3], msg[4], msg[5], msg[6], msg[7]);
break;
case WM_MOVED:
wind_set(msg[3], WF_CURRXYWH, msg[4], msg[5], msg[6], msg[7]);
break;
}
}
/*
* Ein alternatives Binding für fsel_exinput() (Die Funktionsnummer ist
* identisch!), das die Übergabe der Callback-Adresse erlaubt. Andere
* Fileselectoren sollten den überzähligen Parameter einfach ignorieren.
*
* Eine Assembler-Version dieses Bindings, die keine Annahmen über das
* Vorhandensein eines generellen GEM-Traps (hier: '_crystal') im
* verwendeten Entwicklungssystem macht, befindet sich im Quelltext in
* 'BOXINPUT.S' und als Objektdatei im DRI-Format in 'BOXINPUT.O'.
*/
int cdecl fsel_boxinput(char *path, char *name, int *button, char *label, FSEL_CALLBACK callback)
{ void *aespb[6], *addrin[6], *addrout[6];
int contrl[5], global[15], intin[16], intout[7];
aespb[0] = contrl;
aespb[1] = global;
aespb[2] = intin;
aespb[3] = intout;
aespb[4] = addrin;
aespb[5] = addrout;
contrl[0] = 91;
contrl[1] = 0;
contrl[2] = 2;
contrl[3] = 4;
contrl[4] = 0;
addrin[0] = path;
addrin[1] = name;
addrin[2] = label;
addrin[3] = callback;
_crystal((AESPB *)aespb);
*button = intout[1];
return intout[0];
}
int main(void)
{ XDTA mydta;
char path[130], name[34], outbuf[300];
int exbtn, rv, d, i;
appl_init();
wind_get(0, WF_WORKXYWH, &xdesk, &ydesk, &wdesk, &hdesk);
slct_cookie = (SLCT_STR *)get_cookie('FSEL');
if ( !Supexec(setup_selector) )
{ form_alert(1, "[1][Kein kompatibler Fileselector|installiert.][ Ok ]");
appl_exit();
return 0;
}
Pdomain(1); /* Damit auch wirklich lange Namen rauskommen */
/*
* Ein Fenster hinter dem Fileselector öffenen, damit man sieht,
* daß auch etwas beim Message-Callback ankommt.
*/
window = wind_create(NAME | MOVER, xdesk, ydesk, wdesk, hdesk);
if ( window < 0 )
{ form_alert(1, "[1][Das Fenster klemmt mal wieder!][ Ok ]");
appl_exit();
return 0;
}
wind_set(window, WF_NAME, "Noch'n Fenster");
wind_open(window, xdesk + 50, ydesk + 50, 300, 200);
window_redraw(window, xdesk, ydesk, wdesk, hdesk);
getpath(path);
strcat(path, "*.*");
*name = 0;
#if RETURN == 1
do
{ Supexec(setup_selector);
rv = fsel_boxinput(path, name, &exbtn, "BoxKite", &message_handler);
if ( rv && exbtn )
{ Supexec(get_out_count);
for ( i = 0; i < name_count; i++ )
{ sprintf(outbuf, "[1][Datei Nr: %d|%s][ Ok ]", i + 1, nameptrs[i]);
form_alert(1, outbuf);
}
}
}
while ( rv && exbtn );
#elif RETURN == 2
do
{ Supexec(setup_selector);
rv = fsel_boxinput(path, name, &exbtn, "BoxKite", &message_handler);
if ( rv && exbtn )
{ sprintf(outbuf, "[1][%s][ Ok ]", stringbuf);
form_alert(1, outbuf);
}
}
while ( rv && exbtn );
#else
do
{ Supexec(setup_selector);
rv = fsel_boxinput(path, name, &exbtn, "BoxKite", &message_handler);
if ( rv && exbtn )
{ wind_update(BEG_UPDATE);
d = p_get_first(&mydta, 0xff);
i = 1;
while( !d )
{ sprintf(outbuf, "[1][Datei Nr %d:|%s %02x][ Ok ]", i, mydta.d_fname, mydta.d_attrib);
form_alert(1, outbuf);
d = p_get_next(&mydta);
i++;
}
p_release_dir();
wind_update(END_UPDATE);
}
}
while ( rv && exbtn );
#endif
wind_close(window);
wind_delete(window);
appl_exit();
return 0;
}